﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Common;
using System.Data.Linq;
using System.Linq;
using System.Text;
using Media.Core.Entities;
using System.Data;

namespace Media.Core.Data
{
    internal class DBRepo : IDBRepo
    {
        protected MediaEntitiesDataContext _db;

        [Obsolete("Don't use this class directly, use the Database class.")]
        public DBRepo()
        {
            LoadContext(ConfigurationManager.ConnectionStrings["MovieDBContext"].ConnectionString);
        }

        [Obsolete("Don't use this class directly, use the Database class.")]
        public DBRepo(string connectionstring)
        {
            LoadContext(connectionstring);
        }

        [Obsolete("Don't use this class directly, use the Database class.")]
        public DBRepo(DbConnection conn)
        {
            _db = new MediaEntitiesDataContext(conn);
        }

        private void LoadContext(string connectionstring)
        {
            _db = new MediaEntitiesDataContext(connectionstring);
        }

        public void CommitChanges()
        {
            _db.SubmitChanges(ConflictMode.ContinueOnConflict);
        }

        /// <summary>
        /// Gets the table provided by the type T and returns for querying
        /// </summary>
        private Table<T> GetTable<T>() where T : class
        {
            return _db.GetTable<T>();
        }
        public void Delete<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class
        {
            var query = All<T>().Where(expression);
            GetTable<T>().DeleteAllOnSubmit(query);
        }

        public void Delete<T>(T item) where T : class
        {
            GetTable<T>().DeleteOnSubmit(item);
        }

        public void DeleteAll<T>() where T : class
        {
            var query = All<T>();
            GetTable<T>().DeleteAllOnSubmit(query);
        }

        public void Dispose()
        {
            _db.Dispose();
        }

        /// <summary>
        /// Selects a single object from the DB
        /// </summary>
        /// <typeparam name="T">Linq-to-SQL object to return</typeparam>
        /// <param name="expression">A function to test the element for a condition</param>
        /// <returns></returns>
        public T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class
        {
            return GetTable<T>().SingleOrDefault(expression);
        }

        /// <summary>
        /// Gets all objects from a given table
        /// </summary>
        /// <typeparam name="T">Linq-to-SQL object to return</typeparam>
        /// <returns></returns>
        public IQueryable<T> All<T>() where T : class
        {
            return GetTable<T>().AsQueryable();
        }

        public IQueryable<T> Where<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class
        {
            return GetTable<T>().Where(expression);
        }

        public bool Any<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class
        {
            return GetTable<T>().Any(expression);
        }

        public void Add<T>(T item) where T : class
        {
            GetTable<T>().InsertOnSubmit(item);
        }
        public void Add<T>(IEnumerable<T> items) where T : class
        {
            GetTable<T>().InsertAllOnSubmit(items);
        }
        public MediaEntitiesDataContext Context()
        {
            return _db;
        }
    }
}
